﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace BankServiceHost {

    class BankServiceHost<TService, TContract> {

        private ServiceHost serviceHost;
        private Binding binding;
        private string serviceAddress;
        private string endpointAddress;

        private Thread serviceThread;
        private bool isRunning;
        private Object lockObj;

        public BankServiceHost(
            string serviceAddress,
            string endpointAddress,
            Binding binding) {

            this.binding = binding;
            this.serviceAddress = serviceAddress;
            this.endpointAddress = endpointAddress;
            this.lockObj = new Object();
        }

        public void Start() {
            if (this.isRunning == false) {
                this.serviceThread = new Thread(this.ThreadMethod);
                this.serviceThread.Start();
                lock (this.lockObj) {
                    this.isRunning = true;
                }
            }
        }

        public void Stop() {
            lock (this.lockObj) {
                this.isRunning = false;
            }
            this.serviceThread.Join();
        }

        private void ThreadMethod() {

            try {
                this.serviceHost = new ServiceHost(typeof(TService), new Uri(serviceAddress));
                this.serviceHost.AddServiceEndpoint(typeof(TContract), this.binding, this.endpointAddress);
                this.serviceHost.Open();

                bool localIsRunning;
                lock (this.lockObj) {
                    localIsRunning = this.isRunning;
                }
                while (localIsRunning) {
                    Thread.Sleep(200);
                    lock (this.lockObj) {
                        localIsRunning = this.isRunning;
                    }
                }

                this.serviceHost.Close();

            } catch (Exception) {
                if (this.serviceHost != null) {
                    this.serviceHost.Close();
                }
            }
        }
    }
}
